<?php

namespace common\service;


use common\exception\LogicException;
use common\model\MediaModel;
use common\model\RoleModel;
use common\model\SupplierModel;
use common\model\TenantAuthenticationModel;
use common\model\TenantModel;
use common\model\TenantStepCategoryLevelModel;
use common\model\TenantUserModel;
use common\model\UserModel;
use Illuminate\Support\Arr;
use support\ErrorCode;
use teamones\Request;
use think\Exception;

class TenantAuthenticationService
{
    // 认证第一步字段
    const AUTH_FIRST_STEP_FIELDS = ['tenant_id', 'company_name', 'unified_social_credit_code', 'person_in_charge', 'person_in_charge_phone', 'company_manager_number', 'company_maker_number', 'service_category', 'bank_of_deposit', 'bank_subbranch', 'bank_account', 'bank_account_owner'];
    // 认证第二步字段
    const AUTH_SECOND_STEP_FIELDS = ['legal_person_name', 'legal_id_number'];
    // 认证第一步
    const AUTH_STEP_FIRST = 1;
    // 认证第二步
    const AUTH_STEP_SECOND = 2;

    /**
     * 提交认证
     * @param $data
     * @return array
     * @throws \Throwable
     */
    public function create($data)
    {
        $mediaService = new MediaService();
        $tenantAuthenticationModel = model(TenantAuthenticationModel::class);
        $mediaModel = model(MediaModel::class);
        $currentModuleLinkRelation = $tenantAuthenticationModel->parserFilterModuleRelation(true);
        $resData = [];
        $tenantAuthenticationModel->startTrans();
        try {
            $relationIds = [];
            foreach ($data as $moduleCode => $item) {
                if (empty($item)) {
                    continue;
                }
                if (array_key_exists($moduleCode, $currentModuleLinkRelation)) {

                    switch ($currentModuleLinkRelation[$moduleCode]['module_code']) {
                        case "media":
                            $mediaIds = [];
                            if (!is_many_dimension_array($item)) {
                                $item = [$item];
                            }
                            foreach ($item as $mediaItem) {
                                if (empty($mediaItem)) {
                                    continue;
                                }
                                $mediaService->generateMediaData($mediaItem);
                                $mediaData = $mediaModel->addItem($mediaItem);
                                if (!$mediaData) {
                                    throw new LogicException($mediaModel->getError(), ErrorCode::MEDIA_ADD_FAILURE);
                                }
                                $mediaIds[] = $mediaData['id'];
                            }
                            $relationIds[$moduleCode] = join(',', $mediaIds);
                            break;
                    }
                }
            }
            // 把水平自定义关联数据回插入主表
            foreach ($relationIds as $field => $relationId) {
                $data['tenant_authentication'][$field] = $relationId;
            }
            //不允许传递status,reasons_for_failure字段
            unset($data['tenant_authentication']['reasons_for_failure']);
            $data['tenant_authentication']['status'] = 'to_be_reviewed';

            $commonService = CommonService::instance('tenant_authentication');

            // 存在id
            if (isset($data['tenant_authentication']['id']) && $data['tenant_authentication']['id'] > 0) {
                $data['tenant_authentication']['fdd_auth_status'] = 0;
                $data['tenant_authentication']['fdd_transaction_no'] = "";
                $data['tenant_authentication']['fdd_auth_url'] = "";
                $data['tenant_authentication']['fdd_auth_status_desc'] = "";
                $data['tenant_authentication']['fdd_cert_status'] = 0;
                $resData = $commonService->update($data['tenant_authentication']);
            } else {
                $resData = $commonService->create($data['tenant_authentication']);
            }

            $tenantAuthenticationModel->commit();
        } catch (\Throwable $e) {
            $tenantAuthenticationModel->rollback();
            throw $e;
        }

        // 获取公司的运营角色用户,给每个用户发送一遍短信
        try {
            if (!empty($resData)) {
                $this->notifyOperatorsReviewAuthenticate($resData);
            }
        } catch (\Throwable $e) {
            trace(format_exception_info($e), 'ERR');
        }


        return $resData;

    }

    /**
     * 审核
     * @param $data
     * @return array
     * @throws \Throwable
     */
    public function review($data)
    {
        $tenantStepCategoryLevelModel = model(TenantStepCategoryLevelModel::class);
        $tenantAuthenticationModel = model(TenantAuthenticationModel::class);

        $levelData = $data['level_data'] ?? [];

        $levelDataAdd = $levelData;
        $levelDataUpdate = [];
        if (!empty($levelDataAdd)) {
            $tenantAuthenticationData = $tenantAuthenticationModel->find($data['id']);
            $tenantId = $tenantAuthenticationData['tenant_id'];
            $oldLevelData = $tenantStepCategoryLevelModel->where(['tenant_id' => $tenantId])->select();
            //存在历史数据 需要判断需要更新
            if (!empty($oldLevelData)) {
                $levelDataAdd = [];
                $levelDataDelete = $oldLevelDataAssoc = array_column($oldLevelData, null, 'step_category_id');
                array_map(function ($item) use ($oldLevelDataAssoc, &$levelDataAdd, &$levelDataUpdate, &$levelDataDelete) {
                    if (isset($oldLevelDataAssoc[$item['step_category_id']])) {
                        $item['id'] = $oldLevelDataAssoc[$item['step_category_id']]['id'];
                        $levelDataUpdate[] = $item;
                        unset($levelDataDelete[$item['step_category_id']]);
                    } else {
                        $levelDataAdd[] = $item;
                    }
                }, $levelData);
            }

            // 填充批量添加的默认数据
            $levelDataAdd = array_map(function ($item) use ($tenantId) {
                $item['tenant_id'] = $tenantId;
                $item['created'] = time();
                $item['updated'] = time();
                $item['created_by'] = fill_created_by();
                return $item;
            }, $levelDataAdd);
        }

        $fddService = new FDDService();

        $tenantAuthenticationModel->startTrans();
        try {
            $data['updated'] = time();
            $res = $tenantAuthenticationModel->modifyItem($data);
            if ($res === false && $tenantAuthenticationModel->getErrorCode() != -411112) {
                throw new LogicException($tenantAuthenticationModel->getError(), $tenantAuthenticationModel->getErrorCode());
            }
            if ($res === false) {
                $res = $tenantAuthenticationModel->find($data['id']);
            }
            if (!empty($levelDataUpdate)) {
                $tenantStepCategoryLevelModel->saveAll($levelDataUpdate);
            }
            if (!empty($levelDataAdd)) {
                $tenantStepCategoryLevelModel->addAll($levelDataAdd);
            }
            if (!empty($levelDataDelete)) {
                $deleteId = array_column($levelDataDelete, 'id', 'id');
                $tenantStepCategoryLevelModel->where(['id' => ['IN', implode(',', $deleteId)]])->delete();
            }

            if ($data['status'] == 'active') {

                $tenantService = new TenantService();
                $tenantService->createCompanyChat($res['tenant_id'], $res['created_by']);
                // 审核通过 重新生成实名认证地址
                $fddService->getTenantRealNameAuthUrl([
                    'tenant_id' => $res['tenant_id'],
                    're_new' => 'yes',
                ]);
            }
            $tenantAuthenticationModel->commit();
        } catch (\Throwable $e) {
            $tenantAuthenticationModel->rollback();
            throw $e;
        }
        if ($data['status'] == 'active') {
            try {
                // todo 待更新成最新消息
//                $this->notifyTenantAuthenticationReviewResult($data['id']);
            } catch (\Throwable $e) {
                trace($e->getMessage() . PHP_EOL . $e->getTraceAsString(), "ERR");
            }
        }

        return $res;

    }

    /**
     * 获取供应商认证信息
     * @param $filter
     * @return mixed
     */
    protected function getTenantAuthenticationData($filter)
    {
        /** @var TenantAuthenticationModel $tenantAuthenticationModel */
        $tenantAuthenticationModel = model(TenantAuthenticationModel::class);

        $data = $tenantAuthenticationModel->where($filter)->find();

        if (empty($data)) {
            return null;
        }
        CommonService::getFormatAttrData($tenantAuthenticationModel, $data);
        return $data;
    }

    /**
     * 查询供应商认证信息
     * @param $param
     * @param bool $encrypt
     * @return array
     */
    public function find($param, $encrypt = false)
    {
        $res = [];

        $data = $this->getTenantAuthenticationData($param['filter']);
        if (empty($data)) {
            return null;
        }
        $jsonFields = json_decode($data['json'], true);
        $mediaBusinessLicenseId = $jsonFields['media_business_license'] ?? 0;
        $MediaFrontOfLegalIdId = $jsonFields['media_front_of_legal_id'] ?? 0;
        $mediaReverseOfLegalIdId = $jsonFields['media_reverse_of_legal_id'] ?? 0;

        $mediaIds = [$mediaBusinessLicenseId, $MediaFrontOfLegalIdId, $mediaReverseOfLegalIdId];
        // 获取媒体信息
        $mediaData = $this->getMediasByIds($mediaIds);

        $res['tenant_authentication'] = $data;
        $res['media_business_license'] = $mediaData[$mediaBusinessLicenseId] ?? null;
        $res['media_front_of_legal_id'] = $mediaData[$MediaFrontOfLegalIdId] ?? null;
        $res['media_reverse_of_legal_id'] = $mediaData[$mediaReverseOfLegalIdId] ?? null;
        $res['tenant'] = model(TenantModel::class)->find($data['tenant_id']);

        $tenantStepCategoryLevelModel = model(TenantStepCategoryLevelModel::class);
        $res['level_data'] = $tenantStepCategoryLevelModel
            ->where([
                'tenant_id' => $data['tenant_id']
            ])
            ->field("uuid,created,updated,created_by", true)
            ->select();

        // 数据加密处理
        if ($encrypt) {
            if (!empty($res['tenant_authentication']['legal_id_number'])) {
                $res['tenant_authentication']['legal_id_number'] = substr_replace($data['legal_id_number'], '****', 10, 4);
            }
        }

        return $res;
    }

    /**
     * 根据媒体id获取媒体信息
     * @param $mediaIds
     * @return array
     */
    private function getMediasByIds($mediaIds)
    {
        $mediaIds = array_unique(array_filter($mediaIds, function ($item) {
            return (int)$item > 0;
        }));
        $mediaData = [];
        $mediaModel = model(MediaModel::class);
        if (!empty($mediaIds)) {
            $mediaModel->emptyComplexFilterRelatedModule();
            $mediaData = $mediaModel->where(['id' => ['IN', implode(',', $mediaIds)]])->select();
            $mediaData = array_column($mediaData, null, 'id');

            if (!empty($mediaData)) {
                $mediaData = array_map(function ($item) {
                    foreach ($item as $key => &$mediaVal) {
                        $mediaVal = model(MediaModel::class)->getComplexAttr($key, $mediaVal, 'media');
                    }
                    unset($mediaVal);
                    return $item;
                }, $mediaData);
            }
        }
        return $mediaData;
    }

    /**
     * 获取供应商详情
     * @param $supplierId
     * @return array
     */
    public function getSupplierDetails($supplierId)
    {
        $detailsInfo = [
            'base' => [],
            'attestation' => [],
            'case_customer' => [],
            'business' => []
        ];

        // 1. 查找供应商所属租户id
        $supplierModel = model(SupplierModel::class);
        $tenantId = $supplierModel->where(['id' => $supplierId])->getField('from_tenant_id');

        if (empty($tenantId)) {
            return $detailsInfo;
        }

        // 2. 查询当前租户认证信息
        $tenantAuthData = $this->getTenantAuthenticationData(['tenant_id' => $tenantId]);

        if (empty($tenantAuthData)) {
            return $detailsInfo;
        }

        // 3. 组装返回数据

        // 3.1 基本信息
        $detailsInfo['base'] = [
            "person_in_charge" => $tenantAuthData['person_in_charge'],
            "person_in_charge_phone" => $tenantAuthData['person_in_charge_phone'],
            "person_in_charge_email" => $tenantAuthData['person_in_charge_email'],
            "company_web_site" => $tenantAuthData['company_web_site'],
            "unified_social_credit_code" => $tenantAuthData['unified_social_credit_code'], // 企业税号就是营业执照号
            "bank_of_deposit" => $tenantAuthData['bank_of_deposit'],
            "bank_subbranch" => $tenantAuthData['bank_subbranch'],
            "bank_account" => $tenantAuthData['bank_account'],
            "bank_account_owner" => $tenantAuthData['bank_account_owner']

        ];

        // 3.2 认证信息

        $tenantStepCategoryLevelModel = model(TenantStepCategoryLevelModel::class);
        $levelData = $tenantStepCategoryLevelModel
            ->where([
                'tenant_id' => $tenantId
            ])
            ->field("uuid,created,updated,created_by", true)
            ->select();

        $detailsInfo['attestation'] = [
            "company_staff_number" => $tenantAuthData['company_staff_number'],
            "company_manager_number" => $tenantAuthData['company_manager_number'],
            "company_maker_number" => $tenantAuthData['company_maker_number'],
            "level_data" => $levelData,
            "office_hardware" => $tenantAuthData['office_hardware'],
            "secrecy_level" => $tenantAuthData['secrecy_level']
        ];

        // 3.3 案例与客户
        $detailsInfo['case_customer'] = [
            "company_profile" => $tenantAuthData['company_profile'],
            "company_success_stories" => $tenantAuthData['company_success_stories'],
            "company_demo_links" => $tenantAuthData['company_demo_links'],
            "company_customer_service" => $tenantAuthData['company_customer_service']
        ];

        // 3.4 工商信息
        $detailsInfo['business'] = [
            "company_name" => $tenantAuthData['company_name'],
            'company_found_date' => $tenantAuthData['company_found_date'],
            "unified_social_credit_code" => $tenantAuthData['unified_social_credit_code'],
            "company_registered_address" => $tenantAuthData['company_registered_address'],
            "company_business_scope" => $tenantAuthData['company_business_scope'],
            "operation_period_end" => $tenantAuthData['operation_period_end'],
            "legal_person_name" => $tenantAuthData['legal_person_name'],
            "legal_phone" => $tenantAuthData['legal_phone']
        ];

        return $detailsInfo;
    }

    /**
     * 通知审核结果
     * @param $id
     * @throws \Exception
     */
    private function notifyTenantAuthenticationReviewResult($id)
    {
        $tenantAuthData = model(TenantAuthenticationModel::class)->find($id);
        $isPass = $tenantAuthData['status'] == "active";

        $messageParam = [
            'first' => '请查看认证结果',
            'keyword1' => date("Y/m/d H:i"),
            'keyword2' => $isPass ? "通过" : "未通过",
        ];
        if (!$isPass) {
            $messageParam['keyword3'] = $tenantAuthData['reasons_for_failure'];
            $messageParam['remark'] = "请重新填写认证信息";

        } else {
            $messageParam['remark'] = "请及时处理";
        }
        $actions = [
            [
                'key' => "auth_tenant_auth",
                'text' => '查看详情',
                'param' => null
            ],
        ];
        $messageService = new MessageService();
        $messageTemplateId = $this->getNotifyTenantAuthenticationReviewResultTemplateId($isPass);

        $messageService->sendSystemNoticeMessageForHuman($messageParam, $tenantAuthData['created_by'], $messageTemplateId, 'card_message', '', $actions, 'approval');

    }

    /**
     * 获得租户认证通知模板id
     * @param bool $pass
     * @return int
     */
    private function getNotifyTenantAuthenticationReviewResultTemplateId(bool $pass)
    {
        $key = 'notify_tenant_authentication_review_result_template_id_deny';
        if ($pass) {
            $key = "notify_tenant_authentication_review_result_template_id";
        }
        $optionService = new OptionsService();
        $messageTemplateId = $optionService->getOptionsConfigItemData('message_notify_template_config', $key);
        return (int)$messageTemplateId;
    }

    /**
     * 修改租户等级数据
     * @return array|false|mixed|string|null
     * @throws Exception
     * @throws \Throwable
     */
    public function changeTenantStepCategoryLevel($data)
    {

        $tenantStepCategoryLevelModel = model(TenantStepCategoryLevelModel::class);
        $tenantAuthenticationModel = model(TenantAuthenticationModel::class);

        $levelData = $data['level_data'] ?? [];
        $levelDataDelete = [];
        $levelDataAdd = $levelData;
        $tenantAuthenticationData = $tenantAuthenticationModel->find($data['id']);
        $tenantId = $tenantAuthenticationData['tenant_id'];
        $keepStepCategoryIdList = '';
        $changeStepCategory = false;
        if (!empty($levelDataAdd)) {
            $changeStepCategory = true;
            $keepStepCategoryIdList = implode(',', array_column($levelData, 'step_category_id'));
            $oldLevelData = $tenantStepCategoryLevelModel->where(['tenant_id' => $tenantId])->select();
            //存在历史数据 需要判断需要更新
            if (!empty($oldLevelData)) {
                $levelDataAdd = [];
                $levelDataDelete = $oldLevelDataAssoc = array_column($oldLevelData, null, 'step_category_id');
                array_map(function ($item) use ($oldLevelDataAssoc, &$levelDataAdd, &$levelDataUpdate, &$levelDataDelete) {
                    if (isset($oldLevelDataAssoc[$item['step_category_id']])) {
                        $item['id'] = $oldLevelDataAssoc[$item['step_category_id']]['id'];
                        $levelDataUpdate[] = $item;
                        unset($levelDataDelete[$item['step_category_id']]);
                    } else {
                        $levelDataAdd[] = $item;
                    }
                }, $levelData);
            }
            // 填充批量添加的默认数据
            $levelDataAdd = array_map(function ($item) use ($tenantId) {
                $item['tenant_id'] = $tenantId;
                $item['created'] = time();
                $item['updated'] = time();
                $item['created_by'] = fill_created_by();
                return $item;
            }, $levelDataAdd);
        }
        $supplierData = model(SupplierModel::class)->where(['from_tenant_id' => $tenantId, 'type' => 'outside'])->field('id')->select();
        $supplierIdList = array_column($supplierData, 'id');
        $tenantAuthenticationModel->startTrans();
        try {
            $res = $tenantAuthenticationModel->modifyItem($data);
            if ($res === false && $tenantAuthenticationModel->getErrorCode() != -411112) {
                throw new LogicException($tenantAuthenticationModel->getError(), $tenantAuthenticationModel->getErrorCode());
            }
            if ($res === false) {
                $res = $tenantAuthenticationModel->find($data['id']);
            }
            if (!empty($levelDataUpdate)) {
                $tenantStepCategoryLevelModel->saveAll($levelDataUpdate);
            }
            if (!empty($levelDataAdd)) {
                $tenantStepCategoryLevelModel->addAll($levelDataAdd);
            }
            if (!empty($levelDataDelete)) {
                $deleteId = array_column($levelDataDelete, 'id', 'id');
                $tenantStepCategoryLevelModel->where(['id' => ['IN', implode(',', $deleteId)]])->delete();
            }
            if (!empty($supplierIdList) && $changeStepCategory) {
                model(SupplierModel::class)->where(['id' => ['IN', implode(',', $supplierIdList)]])->save(['step_category_ids' => $keepStepCategoryIdList]);
            }
            $tenantAuthenticationModel->commit();
        } catch (\Throwable $e) {
            $tenantAuthenticationModel->rollback();
            throw $e;
        }
        return $res;
    }

    /**
     * 查询租户认证信息 加密
     * @param $param
     * @return array|null
     */
    public function findTenantAuthentication($param): ?array
    {
        return $this->find($param, true);
    }

    /**
     * 短信通知平台运营审核认证
     * @param $tenantAuthentication
     * @return array
     * @throws Exception
     */
    public function notifyOperatorsReviewAuthenticate($tenantAuthentication)
    {
        $tenantId = $tenantAuthentication['tenant_id'];
        $role = model(RoleModel::class)->where(['code' => "operators"])->field("id")->find();

        if (empty($role)) {
            throw new LogicException("role not found", ErrorCode::ROLE_NOT_FOUND);
        }

        //运营为平台级角色 与租户没有关系
        $tenantUser = model(TenantUserModel::class)->where(["role_id" => $role['id']])->field("user_id")->group("user_id")->select();

        if (empty($tenantUser)) {
            return [];
        }

        $userIds = array_column($tenantUser, 'user_id');
        $user = model(UserModel::class)->where(['id' => ["IN", $userIds]])->field("id,phone")->select();
        $phoneList = array_column($user, 'phone', 'id');

        $dataList = [];
        foreach ($phoneList as $phone) {
            $dataList[] = [
                'phone' => $phone,
                'template' => 'tenant_authenticate_review_notify_operators',
                'data' => [
                    $tenantAuthentication['company_name']
                ]
            ];
        }

        Request::connection()
            ->setHeader([
                'X-Userinfo' => request()->getXUserInfo(),
            ])
            ->setServerHost('teamones-oauth')
            ->setRoute('sms/batch_send')
            ->setBody([
                'data_list' => $dataList
            ])
            ->setMethod('POST')
            ->request();
    }

    /**
     * 保存团队认证信息
     * @param $tenantId [团队id]
     * @param $params {"company_name": 团队名称, "service_category": 服务类型, "name": 姓名, "phone": 电话, "id_number": 身份证号, "media_front_of_id": 身份证正面, "media_reverse_of_id": 身份证反面}
     * @return array|bool
     * @throws \Exception
     */
    public function saveTenantAuthentication($tenantId, $params)
    {
        $data = [
            'tenant_id' => $tenantId,
            // 法人信息
            'legal_person_name' => $params['name'],
            'legal_phone' => $params['phone'],
            'legal_id_number' => $params['id_number']
        ];
        // 创建团队时服务类型不需要设置
        if (!empty($params['service_category'])) {
            $data['service_category'] = $params['service_category'];
        }
        // 更新团队信息团队名称不需要修改
        if (!empty($params['company_name'])) {
            $data['company_name'] = $params['company_name'];
        }
        // 身份证正反面
        $medias = [
            'media_front_of_legal_id' => $params['media_front_of_id'],
            'media_reverse_of_legal_id' => $params['media_reverse_of_id']
        ];
        // 组装媒体文件数据
        $bulidMediaJson = $this->buildMediaData($medias);

        $tenantAuthenticationModel = model(TenantAuthenticationModel::class);
        $tenantAuthenticationInfo = $tenantAuthenticationModel->where(['tenant_id' => $tenantId])->find();
        if (!empty($tenantAuthenticationInfo)) {
            // 如果存在团队认证信息，则更新
            $data['id'] = $tenantAuthenticationInfo['id'];
            // 更新素材数据，需要将数据库内的媒体文件信息合并
            $mediaJson = json_decode(empty($tenantAuthenticationInfo['json']) ? '{}' : $tenantAuthenticationInfo['json'], true);
            $data['json'] = array_merge($mediaJson, $bulidMediaJson);

            $res = $tenantAuthenticationModel->modifyItem($data);
        } else {
            $data['json'] = $bulidMediaJson;
            // 如果不存在团队认证信息，则创建
            $res = $tenantAuthenticationModel->addItem($data);
        }

        return $res;
    }

    /**
     * 组装媒体信息数据
     * @param $medias
     * @return array
     * @throws \Exception
     */
    public function buildMediaData($medias)
    {
        $data = [];
        foreach ($medias as $k => $item) {
            if (!is_many_dimension_array($item)) {
                $item = [$item];
            }
            $mediaIds = $this->dealMedia($item);
            $data[$k] = join(',', $mediaIds);
        }
        return $data;
    }

    /**
     * 处理素材，并且返回素材id
     * @param $data
     * @return array
     * @throws \Exception
     */
    private function dealMedia($data)
    {
        $mediaIds = [];
        $mediaService = new MediaService();
        $mediaModel = model(MediaModel::class);
        foreach ($data as $mediaItem) {
            if (empty($mediaItem)) {
                continue;
            }
            $mediaService->generateMediaData($mediaItem);
            $mediaData = $mediaModel->addItem($mediaItem);
            if (!$mediaData) {
                throw new LogicException($mediaModel->getError(), ErrorCode::MEDIA_ADD_FAILURE);
            }
            $mediaIds[] = $mediaData['id'];
        }
        return $mediaIds;
    }

    /**
     * 提交营业执照
     * @param $tenantId
     * @param $params
     * @return array|bool
     * @throws \Exception
     */
    public function businessLicenseSubmit($tenantId, $params)
    {
        $data = Arr::only($params, self::AUTH_FIRST_STEP_FIELDS);
        // 更新素材信息
        $medias = Arr::only($params, ['media_business_license']);

        return $this->saveTenantAuthInfo($tenantId, $data, $medias, self::AUTH_STEP_FIRST);
    }

    /**
     * 提交法人证件照
     * @param $tenantId
     * @param $params
     * @return array|bool
     * @throws \Exception
     */
    public function legalPersonSubmit($tenantId, $params)
    {
        $data = Arr::only($params, self::AUTH_SECOND_STEP_FIELDS);
        // 更新素材信息
        $medias = Arr::only($params, ['media_front_of_legal_id', 'media_reverse_of_legal_id']);

        return $this->saveTenantAuthInfo($tenantId, $data, $medias, self::AUTH_STEP_SECOND);
    }

    /**
     * 保存认证信息
     * @param $tenantId
     * @param $data
     * @param $medias
     * @param $step
     * @return array|bool
     * @throws \Exception
     */
    private function saveTenantAuthInfo($tenantId, $data, $medias, $step)
    {
        $data['tenant_id'] = $tenantId;
        $tenantAuthenticationModel = model(TenantAuthenticationModel::class);
        $tenantAuthInfo = $tenantAuthenticationModel->where(['tenant_id' => $tenantId])->find();
        $data['json'] = $this->buildMediaData($medias);
        $data['status'] = TenantAuthenticationModel::STATUS_SUBMITTING;

        if (!empty($tenantAuthInfo)) {
            // 如果未更改数据，就不更新数据
            if (!$this->checkAuthDataIsChange($data, $tenantAuthInfo, $step)) {
                return ['id' => $tenantAuthInfo['id']];
            }

            // 如果是步骤一，则需处理工序等级
            if ($step == self::AUTH_STEP_FIRST) {
                TenantService::getInstance()->dealStepCategoryLevel($tenantId, $data['service_category'], json_decode(empty($tenantAuthInfo['service_category']) ? '{}' : $tenantAuthInfo['service_category'], true));
            }

            // 如果存在认证记录，则更新记录
            $mediaJson = json_decode($tenantAuthInfo['json'], true);
            $data['id'] = $tenantAuthInfo['id'];
            // 更新素材数据
            $data['json'] = array_replace($mediaJson, $data['json']);
            $resData = $tenantAuthenticationModel->modifyItem($data);
        } else {
            $resData = $tenantAuthenticationModel->addItem($data);
        }

        if (empty($resData)) {
            throw_strack_exception($tenantAuthenticationModel->getError(), ErrorCode::SAVE_TENANT_AUTHENTICATION_FAIL);
        }

        return ['id' => $resData['id']];
    }

    /**
     * 校验是否变更过认证数据
     * @param array $params 用户提交的数据
     * @param array $tenantAuthInfo 企业认证数据
     * @param int $step 步骤
     * @return bool true:已变更|false:未变更
     */
    private function checkAuthDataIsChange(array $params, array $tenantAuthInfo, int $step)
    {
        // 将已存在认证信息里面的service_category转换成数组，与提交认证信息的做对比
        if (!empty($tenantAuthInfo['service_category'])) {
            $tenantAuthInfo['service_category'] = json_decode($tenantAuthInfo['service_category'], true);
        }

        // 取出媒体信息
        $mediaJson = json_decode(empty($tenantAuthInfo['json']) ? '{}' : $tenantAuthInfo['json'], true);

        // 将营业执照、身份证正反面加入到对比项，
        if ($step == self::AUTH_STEP_FIRST) {
            // 增加营业执照信息对比
            $stepFields = array_merge(self::AUTH_FIRST_STEP_FIELDS, ['media_business_license']);
            $updateMediasIds['media_business_license'] = $params['json']['media_business_license'] ?? 0;
            $oldMediasIds['media_business_license'] = $mediaJson['media_business_license'] ?? 0;
        } else {
            // 增加身份证信息对比
            $stepFields = array_merge(self::AUTH_SECOND_STEP_FIELDS, ['media_front_of_legal_id', 'media_reverse_of_legal_id']);
            $updateMediasIds['media_front_of_legal_id'] = $params['json']['media_front_of_legal_id'] ?? 0;
            $updateMediasIds['media_reverse_of_legal_id'] = $params['json']['media_reverse_of_legal_id'] ?? 0;
            $oldMediasIds['media_front_of_legal_id'] = $mediaJson['media_front_of_legal_id'] ?? 0;
            $oldMediasIds['media_reverse_of_legal_id'] = $mediaJson['media_reverse_of_legal_id'] ?? 0;
        }

        // 校验媒体信息是否更新
        $mediaIsChange = $this->checkMediaIsChange($updateMediasIds, $oldMediasIds, array_keys($oldMediasIds));
        if ($mediaIsChange) {
            return true;
        }

        // 获取除媒体信息的其他指定字段
        $params = Arr::only($params, $stepFields);
        $tenantAuthInfo = Arr::only($tenantAuthInfo, $stepFields);

        return $params != $tenantAuthInfo;
    }

    /**
     * 根据媒体信息md5校验是否更新
     * @param array $updateMediasIds 待更新的媒体信息id
     * @param array $oldMediasIds 数据库中的旧媒体信息id
     * @param array $keys 媒体信息数组的键名
     * @return bool true:已变更|false:未变更
     */
    private function checkMediaIsChange(array $updateMediasIds, array $oldMediasIds, array $keys)
    {
        $updateMedias = $this->getMediasByIds($updateMediasIds);
        $oldMedias = $this->getMediasByIds($oldMediasIds);

        foreach ($keys as $key) {
            $updateMediaMd5 = $updateMedias[$updateMediasIds[$key]]['md5_name'] ?? '';
            $oldMediaMd5 = $oldMedias[$oldMediasIds[$key]]['md5_name'] ?? '';
            // 对比媒体信息md5是不一致，不一致说明媒体信息已更新
            if ($updateMediaMd5 !== $oldMediaMd5) {
                return true;
            }
        }

        return false;
    }

    /**
     * 认证信息提交审核
     * @param $tenantId
     * @param $params
     * @return array|bool
     * @throws \Exception
     */
    public function submitAudit($tenantId, $params)
    {
        $id = $params['id'];
        $tenantAuthenticationModel = model(TenantAuthenticationModel::class);
        $tenantAuthenticationInfo = $tenantAuthenticationModel->field(['tenant_id', 'status'])->where(['id' => $id])->find();
        if (empty($tenantAuthenticationInfo)) {
            throw_strack_exception("The record does not exist", ErrorCode::MISSING_TENANT_AUTHENTICATION_INFO);
        }

        // 不允许提交其他团队的团队认证信息
        if ($tenantId != $tenantAuthenticationInfo['tenant_id']) {
            throw_strack_exception("Other tenant are not allowed to operate", ErrorCode::TENANT_AUTHENTICATION_NOT_ALL_OPERATION);
        }

        // 已经处于审核状态就无需再次提交
        if ($tenantAuthenticationInfo['status'] == TenantAuthenticationModel::STATUS_TO_BE_REVIEWED) {
            return [];
        }

        $data = [
            'id' => $id,
            'status' => TenantAuthenticationModel::STATUS_TO_BE_REVIEWED,
            // 法大大认证信息恢复默认值
            'fdd_auth_status' => 0,
            'fdd_transaction_no' => '',
            'fdd_auth_url' => '',
            'fdd_auth_status_desc' => '',
            'fdd_cert_status' => 0
        ];
        $resData = $tenantAuthenticationModel->modifyItem($data);
        if (empty($resData)) {
            throw_strack_exception($tenantAuthenticationModel->getError(), ErrorCode::SUBMIT_REVIEW_FAIL);
        }
        // 获取公司的运营角色用户,给每个用户发送一遍短信
        try {
            $this->notifyOperatorsReviewAuthenticate($resData);
        } catch (\Throwable $e) {
            trace(format_exception_info($e), 'ERR');
        }
        return $resData;
    }
}
